﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.UI;
using YArchitech.LIB;
using YArchitech.MEP;
using YArchitech.ProgressBar;
using YArchitech.Revit;

namespace YArchitech.HVAC
{
	public class SprinklerShelter
	{
		public SprinklerShelter()
		{
		}

		public SprinklerShelter(List<Element> list)
		{
			this.listModify = list;
		}

		public ICollection<ElementId> GetPriorFitting(Autodesk.Revit.DB.Document doc)
		{
			return this.GetAllFamilyInstance(doc, BuiltInCategory.OST_PipeFitting);
		}

		public void SetFittingEmptyLen(Autodesk.Revit.DB.Document doc, ICollection<ElementId> priFittings, int nDiameter, bool bNewTran)
		{
			try
			{
				ICollection<ElementId> allFamilyInstance = this.GetAllFamilyInstance(doc, BuiltInCategory.OST_PipeFitting);
				IEnumerable<ElementId> enumerable = new List<ElementId>();
				new List<Element>();
				if (priFittings != null && priFittings.Count > 0)
				{
					enumerable = priFittings.Intersect(allFamilyInstance);
					if (enumerable.Count<ElementId>() > 0)
					{
						foreach (ElementId item in enumerable)
						{
							allFamilyInstance.Remove(item);
						}
					}
				}
				PipeConfigurationManagement.SetEmptyLength((double)nDiameter, doc, allFamilyInstance, bNewTran);
			}
			catch
			{
			}
		}

		public void DeleteElbowAndTee(Autodesk.Revit.DB.Document doc, ICollection<ElementId> priFittings)
		{
			try
			{
				foreach (ElementId elementId in priFittings)
				{
					Element elementById = doc.GetElementById(elementId);
					if (elementById is FamilyInstance)
					{
						FamilyInstance familyInstance = elementById as FamilyInstance;
						if (familyInstance != null && familyInstance.MEPModel != null && familyInstance.MEPModel is MechanicalFitting && ((int)(familyInstance.MEPModel as MechanicalFitting).PartType == 6 || (int)(familyInstance.MEPModel as MechanicalFitting).PartType == 5))
						{
							doc.DeleteElement(elementById);
						}
					}
				}
			}
			catch
			{
			}
		}

		public List<Element> NeedConnectPipes(Autodesk.Revit.DB.Document doc, ICollection<ElementId> priFittings)
		{
			List<Element> list = new List<Element>();
			try
			{
				this.GetAllFamilyInstance(doc, BuiltInCategory.OST_PipeCurves);
				foreach (ElementId elementId in priFittings)
				{
					Element elementById = doc.GetElementById(elementId);
					if (elementById is FamilyInstance)
					{
						FamilyInstance familyInstance = elementById as FamilyInstance;
						if (familyInstance != null && familyInstance.MEPModel != null && familyInstance.MEPModel is MechanicalFitting && ((int)(familyInstance.MEPModel as MechanicalFitting).PartType == 5 || (int)(familyInstance.MEPModel as MechanicalFitting).PartType == 6))
						{
							ConnectorSetIterator connectorSetIterator = familyInstance.MEPModel.ConnectorManager.Connectors.ForwardIterator();
							while (connectorSetIterator.MoveNext())
							{
								object obj = connectorSetIterator.Current;
								Connector connector = obj as Connector;
								if (connector != null)
								{
									Pipe connectedPipe = this.GetConnectedPipe(connector);
									list.Add(connectedPipe);
								}
							}
						}
					}
				}
			}
			catch
			{
			}
			return list;
		}

		private Pipe GetConnectedPipe(Connector connector)
		{
			if (connector == null)
			{
				return null;
			}
			Connector connectedConnector = connector.GetConnectedConnector();
			if (connectedConnector == null || connectedConnector.Owner == null)
			{
				return null;
			}
			if (connectedConnector.Owner is Pipe)
			{
				return connectedConnector.Owner as Pipe;
			}
			if (connectedConnector.Owner is FamilyInstance && (connectedConnector.Owner as FamilyInstance).MEPModel != null && (int)((connectedConnector.Owner as FamilyInstance).MEPModel as MechanicalFitting).PartType == 7)
			{
				foreach (object obj in (connectedConnector.Owner as FamilyInstance).MEPModel.ConnectorManager.Connectors)
				{
					Connector connector2 = (Connector)obj;
					if (connector2 != connectedConnector && !connector2.Origin.IsAlmostEqualTo(connectedConnector.Origin, 1E-06))
					{
						return this.GetConnectedPipe(connector2);
					}
				}
			}
			return null;
		}

		public void SetAfterFitting(Autodesk.Revit.DB.Document doc, ICollection<ElementId> priFittings, FamilySymbol sprinkle, PipeType pipeType, bool bNewTran, YJKWindowHandle revHand = null)
		{
			Transaction transaction = null;
			Dictionary<int, IList<RoutingPreferenceRule>> dictionary = null;
			ProgressBarForm progressBarForm = null;
			try
			{
				int sprinklerDiameter = PipeConfigurationManagement.GetSprinklerDiameter(sprinkle);
				if (sprinklerDiameter > 0)
				{
					if (revHand != null)
					{
						progressBarForm = new ProgressBarForm(4, ProgressBarStyle.Blocks, true);
						progressBarForm.Text = "三通替换 请稍后...";
						progressBarForm.RefreshProgressBar();
						if (progressBarForm.m_stopTag)
						{
							return;
						}
					}
					ICollection<ElementId> allFamilyInstance = this.GetAllFamilyInstance(doc, BuiltInCategory.OST_PipeFitting);
					IEnumerable<ElementId> enumerable = new List<ElementId>();
					new List<Element>();
					if (priFittings != null && priFittings.Count > 0)
					{
						enumerable = priFittings.Intersect(allFamilyInstance);
						if (enumerable.Count<ElementId>() > 0)
						{
							foreach (ElementId item in enumerable)
							{
								allFamilyInstance.Remove(item);
							}
						}
					}
					if (revHand != null)
					{
						progressBarForm.RefreshProgressBar();
						if (progressBarForm.m_stopTag)
						{
							return;
						}
					}
					if (pipeType != null)
					{
						dictionary = PipeConfigurationManagement.GetRules(pipeType, doc, bNewTran, 1);
					}
					if (revHand != null)
					{
						progressBarForm.RefreshProgressBar();
						if (progressBarForm.m_stopTag)
						{
							return;
						}
					}
					if (bNewTran)
					{
						transaction = new Transaction(doc, "更换管件");
						transaction.Start();
						foreach (ElementId elementId in allFamilyInstance)
						{
							if (revHand != null && progressBarForm.m_stopTag)
							{
								return;
							}
							ElementNode eNode = new ElementNode(doc.GetElementById(elementId));
							this.SetFittingLeng(eNode, doc, (double)sprinklerDiameter);
						}
						doc.Regenerate();
						transaction.Commit();
					}
					else
					{
						foreach (ElementId elementId2 in allFamilyInstance)
						{
							if (revHand != null && progressBarForm.m_stopTag)
							{
								return;
							}
							ElementNode eNode2 = new ElementNode(doc.GetElementById(elementId2));
							this.SetFittingLeng(eNode2, doc, (double)sprinklerDiameter);
						}
					}
					allFamilyInstance = this.GetAllFamilyInstance(doc, BuiltInCategory.OST_PipeFitting);
					enumerable = new List<ElementId>();
					new List<Element>();
					if (revHand == null || !progressBarForm.m_stopTag)
					{
						if (priFittings != null && priFittings.Count > 0)
						{
							enumerable = priFittings.Intersect(allFamilyInstance);
							if (enumerable.Count<ElementId>() > 0)
							{
								foreach (ElementId item2 in enumerable)
								{
									if (revHand != null && progressBarForm.m_stopTag)
									{
										return;
									}
									allFamilyInstance.Remove(item2);
								}
							}
						}
						if (revHand == null || !progressBarForm.m_stopTag)
						{
							PipeConfigurationManagement.SetEmptyLength((double)sprinklerDiameter, doc, allFamilyInstance, bNewTran);
						}
					}
				}
			}
			catch
			{
			}
			finally
			{
				if (revHand != null && progressBarForm != null)
				{
					progressBarForm.Dispose();
				}
				if (transaction != null && (int)(int)transaction.GetStatus() != 3)
				{
					transaction.RollBack();
				}
				if (dictionary != null && pipeType != null)
				{
					PipeConfigurationManagement.SetRules(pipeType, doc, dictionary, bNewTran);
				}
			}
		}

		public void SetBlankLength(ElementNode eNode, UIDocument uiDoc)
		{
			Transaction transaction = null;
			Dictionary<int, IList<RoutingPreferenceRule>> dictionary = null;
			PipeType pipeType = null;
			try
			{
				int sprinklerDiameter = PipeConfigurationManagement.GetSprinklerDiameter(this.GetSprinkle(eNode));
				if (sprinklerDiameter > 0)
				{
					pipeType = (eNode.Element as Pipe).PipeType;
					dictionary = PipeConfigurationManagement.GetRules(pipeType, uiDoc.Document, true, 1);
					IEnumerable<ElementId> allFamilyInstance = this.GetAllFamilyInstance(uiDoc.Document, BuiltInCategory.OST_PipeFitting);
					transaction = new Transaction(uiDoc.Document, "更换管件");
					transaction.Start();
					this.ChangeFitting(eNode, uiDoc.Document, (double)sprinklerDiameter);
					uiDoc.Document.Regenerate();
					transaction.Commit();
					ICollection<ElementId> allFamilyInstance2 = this.GetAllFamilyInstance(uiDoc.Document, BuiltInCategory.OST_PipeFitting);
					IEnumerable<ElementId> enumerable = new List<ElementId>();
					new List<Element>();
					enumerable = allFamilyInstance.Intersect(allFamilyInstance2);
					if (enumerable.Count<ElementId>() > 0)
					{
						foreach (ElementId item in enumerable)
						{
							allFamilyInstance2.Remove(item);
						}
					}
					PipeConfigurationManagement.SetEmptyLength((double)sprinklerDiameter, uiDoc.Document, allFamilyInstance2, true);
				}
			}
			catch (Exception ex)
			{
				string message = ex.Message;
			}
			finally
			{
				if (transaction != null && (int)(int)transaction.GetStatus() != 3)
				{
					transaction.RollBack();
				}
				if (dictionary != null && pipeType != null)
				{
					PipeConfigurationManagement.SetRules(pipeType, uiDoc.Document, dictionary, true);
				}
			}
		}

		private void ModifyCross(ElementNode eNode, Autodesk.Revit.DB.Document doc)
		{
			if (eNode != null && eNode.Element != null && eNode.Element.IsValidObject)
			{
				if (eNode.Element is FamilyInstance && eNode.Element is FamilyInstance && (eNode.Element as FamilyInstance).MEPModel != null && (eNode.Element as FamilyInstance).MEPModel is MechanicalFitting)
				{
					MechanicalFitting mechanicalFitting = (eNode.Element as FamilyInstance).MEPModel as MechanicalFitting;
					if ((int)mechanicalFitting.PartType == 8 || (int)mechanicalFitting.PartType == 6)
					{
						this.MidofyFittingByPipe(eNode.Element as FamilyInstance, doc);
					}
				}
				this.ModifyCross(eNode.Next, doc);
				if (eNode.SubElementNode != null)
				{
					foreach (ElementNode eNode2 in eNode.SubElementNode)
					{
						this.ModifyCross(eNode2, doc);
					}
				}
			}
		}

		private List<Connector> GetConnectotFour(List<Pipe> pipeList, XYZ Point)
		{
			List<Connector> list = new List<Connector>();
			foreach (Pipe piping in pipeList)
			{
				YJKPiping<Pipe> hypiping = new YJKPiping<Pipe>(piping);
				list.Add(hypiping.GetCloseConnector(Point, false));
			}
			return list;
		}

		private FamilySymbol GetSprinkle(ElementNode eNode)
		{
			if (eNode != null && eNode.Element != null && eNode.Element.IsValidObject)
			{
				if (eNode.Element is FamilyInstance && eNode.Element.Category.Id.IntegerValue == -2008099)
				{
					return (eNode.Element as FamilyInstance).Symbol;
				}
				FamilySymbol sprinkle = this.GetSprinkle(eNode.Next);
				if (sprinkle != null)
				{
					return sprinkle;
				}
				if (eNode.SubElementNode != null)
				{
					foreach (ElementNode eNode2 in eNode.SubElementNode)
					{
						FamilySymbol sprinkle2 = this.GetSprinkle(eNode2);
						if (sprinkle2 != null)
						{
							return sprinkle2;
						}
					}
				}
			}
			return null;
		}

		public ICollection<ElementId> GetAllFamilyInstance(Autodesk.Revit.DB.Document doc, BuiltInCategory builtInCategory)
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			new ElementOwnerViewFilter(doc.ActiveView.Id);
			return filteredElementCollector.OfCategory(builtInCategory).OfClass(typeof(FamilyInstance)).ToElementIds();
		}

		private bool IsContainsElement(Element ent)
		{
			if (this.listModify == null || this.listModify.Count < 1)
			{
				return false;
			}
			foreach (Element element in this.listModify)
			{
				if (element.IsValidObject && element.Id.IntegerValue == ent.Id.IntegerValue)
				{
					return true;
				}
			}
			return false;
		}

		private void ChangeFitting(ElementNode eNode, Autodesk.Revit.DB.Document doc, double dLen)
		{
			if (eNode == null)
			{
				return;
			}
			if (eNode.Element.IsValidObject && eNode.Element is Pipe && !this.IsContainsElement(eNode.Element))
			{
				return;
			}
			this.SetFittingLeng(eNode, doc, dLen);
			this.ChangeFitting(eNode.Next, doc, dLen);
			if (eNode.SubElementNode != null)
			{
				foreach (ElementNode elementNode in eNode.SubElementNode)
				{
					this.ChangeFitting(elementNode.Next, doc, dLen);
				}
			}
		}

		public static void SetFittingLenth(FamilyInstance fitting, Autodesk.Revit.DB.Document doc, double dLength)
		{
			if (fitting == null)
			{
				return;
			}
			if (fitting.MEPModel != null && fitting.MEPModel is MechanicalFitting)
			{
				YJKRotateFamilyInstance hyrotateFamilyInstance = new YJKRotateFamilyInstance();
				MechanicalFitting mechanicalFitting = fitting.MEPModel as MechanicalFitting;
				if ((int)mechanicalFitting.PartType == 6)
				{
					if (fitting.Symbol.FamilyName == "变径三通_空白")
					{
						Parameter parameter = fitting.GetParameter("空白区域长度");
						if (parameter != null && !parameter.IsReadOnly)
						{
							if (dLength <= 0.0)
							{
								dLength = 20.0;
							}
							parameter.Set(dLength / 304.8);
							Parameter parameter2 = fitting.GetParameter(BuiltInParameter.RBS_FAMILY_CONTENT_ANNOTATION_DISPLAY);
							if (parameter2 != null && !parameter2.IsReadOnly)
							{
								parameter2.Set(0);
								PipeConfigurationManagement.SetTranteAnnotations(fitting);
							}
						}
						hyrotateFamilyInstance.MoveFamilyInstance(fitting, new XYZ(0.0, 1.0, 0.0));
						return;
					}
				}
				else if ((int)mechanicalFitting.PartType == 5 && fitting.Symbol.FamilyName == "弯头_空白")
				{
					Parameter parameter3 = fitting.GetParameter("空白区域长度");
					if (parameter3 != null && !parameter3.IsReadOnly)
					{
						parameter3.Set(dLength / 609.6);
						Parameter parameter4 = fitting.GetParameter(BuiltInParameter.RBS_FAMILY_CONTENT_ANNOTATION_DISPLAY);
						if (parameter4 != null && !parameter4.IsReadOnly)
						{
							parameter4.Set(0);
							PipeConfigurationManagement.SetTranteAnnotations(fitting);
						}
					}
					hyrotateFamilyInstance.MoveFamilyInstance(fitting, new XYZ(0.0, 1.0, 0.0));
				}
			}
		}

		private void SetFittingLeng(ElementNode eNode, Autodesk.Revit.DB.Document doc, double dLen)
		{
			if (eNode == null || eNode.Element == null || !eNode.Element.IsValidObject)
			{
				return;
			}
			if (eNode.Element is FamilyInstance && (eNode.Element as FamilyInstance).MEPModel != null && (eNode.Element as FamilyInstance).MEPModel is MechanicalFitting)
			{
				YJKRotateFamilyInstance hyrotateFamilyInstance = new YJKRotateFamilyInstance();
				FamilyInstance familyInstance = eNode.Element as FamilyInstance;
				MechanicalFitting mechanicalFitting = (eNode.Element as FamilyInstance).MEPModel as MechanicalFitting;
				if ((int)mechanicalFitting.PartType == 6)
				{
					if (!this.IsModify(eNode))
					{
						return;
					}
					if (familyInstance.Symbol.FamilyName == "变径三通_空白")
					{
						Parameter parameter = familyInstance.GetParameter("空白区域长度");
						if (parameter != null && !parameter.IsReadOnly)
						{
							parameter.Set(dLen / 304.8);
							Parameter parameter2 = familyInstance.GetParameter(BuiltInParameter.RBS_FAMILY_CONTENT_ANNOTATION_DISPLAY);
							if (parameter2 != null && !parameter2.IsReadOnly)
							{
								parameter2.Set(0);
								PipeConfigurationManagement.SetTranteAnnotations(familyInstance);
							}
						}
						hyrotateFamilyInstance.MoveFamilyInstance(familyInstance, new XYZ(0.0, 1.0, 0.0));
						return;
					}
					new HYPipeConnect().NewSomeConnect(this.GetFittingConnectPipe(eNode.Element as FamilyInstance, doc));
					return;
				}
				else if ((int)mechanicalFitting.PartType == 5)
				{
					if (!this.IsModify(eNode))
					{
						return;
					}
					if (familyInstance.Symbol.FamilyName == "弯头_空白")
					{
						Parameter parameter3 = familyInstance.GetParameter("空白区域长度");
						if (parameter3 != null && !parameter3.IsReadOnly)
						{
							parameter3.Set(dLen / 609.6);
							Parameter parameter4 = familyInstance.GetParameter(BuiltInParameter.RBS_FAMILY_CONTENT_ANNOTATION_DISPLAY);
							if (parameter4 != null && !parameter4.IsReadOnly)
							{
								parameter4.Set(0);
								PipeConfigurationManagement.SetTranteAnnotations(familyInstance);
							}
						}
						hyrotateFamilyInstance.MoveFamilyInstance(familyInstance, new XYZ(0.0, 1.0, 0.0));
						return;
					}
					new HYPipeConnect().NewSomeConnect(this.GetFittingConnectPipe(eNode.Element as FamilyInstance, doc));
				}
			}
		}

		private List<Pipe> GetFittingConnectPipe(FamilyInstance fittingIns, Autodesk.Revit.DB.Document doc)
		{
			List<Pipe> list = new List<Pipe>();
			List<Element> list2 = new List<Element>();
			foreach (object obj in fittingIns.MEPModel.ConnectorManager.Connectors)
			{
				Connector con = (Connector)obj;
				Pipe connectPipe = this.GetConnectPipe(con, ref list2);
				if (connectPipe != null)
				{
					list.Add(connectPipe);
				}
			}
			doc.DeleteElement(fittingIns);
			foreach (Element elem in list2)
			{
				doc.DeleteElement(elem);
			}
			doc.Regenerate();
			return list;
		}

		private void MidofyFittingByPipe(FamilyInstance fittingIns, Autodesk.Revit.DB.Document doc)
		{
			try
			{
				List<Pipe> list = new List<Pipe>();
				List<Element> list2 = new List<Element>();
				foreach (object obj in fittingIns.MEPModel.ConnectorManager.Connectors)
				{
					Connector connector = (Connector)obj;
					Pipe connectPipe = this.GetConnectPipe(connector, ref list2);
					if (connectPipe != null)
					{
						list.Add(connectPipe);
						connector.Radius = connectPipe.Diameter / 2.0;
					}
				}
				doc.Regenerate();
			}
			catch
			{
			}
		}

		private Pipe GetConnectPipe(Connector con, ref List<Element> entDel)
		{
			Connector connectConnector = this.GetConnectConnector(con);
			if (connectConnector == null || connectConnector.Owner == null)
			{
				return null;
			}
			if (connectConnector.Owner is Pipe)
			{
				return connectConnector.Owner as Pipe;
			}
			if (connectConnector.Owner is FamilyInstance && (connectConnector.Owner as FamilyInstance).MEPModel != null && (int)((connectConnector.Owner as FamilyInstance).MEPModel as MechanicalFitting).PartType == 7)
			{
				entDel.Add(connectConnector.Owner);
				foreach (object obj in (connectConnector.Owner as FamilyInstance).MEPModel.ConnectorManager.Connectors)
				{
					Connector connector = (Connector)obj;
					if (connector != connectConnector && !connector.Origin.IsAlmostEqualTo(connectConnector.Origin, 1E-06))
					{
						return this.GetConnectPipe(connector, ref entDel);
					}
				}
			}
			return null;
		}

		private bool IsModify(ElementNode eNode)
		{
			ConnectorSet connectors = this.GetConnectors(eNode.Element);
			int num = 0;
			Connector connector = null;
			foreach (object obj in connectors)
			{
				Connector connector2 = (Connector)obj;
				if (connector2.CoordinateSystem.BasisZ.IsAlmostEqualTo(new XYZ(0.0, 0.0, 1.0), 1E-05))
				{
					num++;
					connector = connector2;
				}
			}
			return num == 1 && connector != null && connector.IsConnected && this.IsConnectToSprinkler(connector);
		}

		private bool IsConnectToSprinkler(Connector con)
		{
			Connector connectConnector = this.GetConnectConnector(con);
			if (connectConnector == null || connectConnector.Owner == null)
			{
				return false;
			}
			if (connectConnector.Owner is FamilyInstance)
			{
				if (connectConnector.Owner.Category.Id.IntegerValue == -2008099)
				{
					return true;
				}
				if ((connectConnector.Owner as FamilyInstance).MEPModel == null || (int)((connectConnector.Owner as FamilyInstance).MEPModel as MechanicalFitting).PartType != 7)
				{
					return false;
				}
				IEnumerator enumerator = (connectConnector.Owner as FamilyInstance).MEPModel.ConnectorManager.Connectors.GetEnumerator();
				{
					while (enumerator.MoveNext())
					{
						object obj = enumerator.Current;
						Connector connector = (Connector)obj;
						if (connector != connectConnector && !connector.Origin.IsAlmostEqualTo(connectConnector.Origin, 1E-06) && this.IsConnectToSprinkler(connector))
						{
							return true;
						}
					}
					return false;
				}
			}
			if (connectConnector.Owner is Pipe)
			{
				foreach (object obj2 in (connectConnector.Owner as Pipe).ConnectorManager.Connectors)
				{
					Connector connector2 = (Connector)obj2;
					if (connector2 != connectConnector && !connector2.Origin.IsAlmostEqualTo(connectConnector.Origin, 1E-06) && this.IsConnectToSprinkler(connector2))
					{
						return true;
					}
				}
			}
			return false;
		}

		public ConnectorSet GetConnectors(Element element)
		{
			if (element == null)
			{
				return null;
			}
			FamilyInstance familyInstance = element as FamilyInstance;
			if (familyInstance != null && familyInstance.MEPModel != null)
			{
				return familyInstance.MEPModel.ConnectorManager.Connectors;
			}
			MEPSystem mepsystem = element as MEPSystem;
			if (mepsystem != null)
			{
				return mepsystem.ConnectorManager.Connectors;
			}
			MEPCurve mepcurve = element as MEPCurve;
			if (mepcurve != null)
			{
				return mepcurve.ConnectorManager.Connectors;
			}
			return null;
		}

		public Connector GetConnectConnector(Connector connector)
		{
			Connector result = null;
			if (connector != null && connector.IsConnected)
			{
				ConnectorSetIterator connectorSetIterator = connector.AllRefs.ForwardIterator();
				while (connectorSetIterator.MoveNext())
				{
					object obj = connectorSetIterator.Current;
					Connector connector2 = obj as Connector;
					if (connector2 != null && connector2.Owner.UniqueId != connector.Owner.UniqueId && ((int)connector2.ConnectorType == 1 || (int)connector2.ConnectorType == 2 || (int)connector2.ConnectorType == 19))
					{
						result = connector2;
						break;
					}
				}
			}
			return result;
		}

		private List<Element> listModify = new List<Element>();
	}
}
